<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>录音应用 - WebM格式保存</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }

        .container {
            background-color: rgba(255, 255, 255, 0.9);
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
            width: 100%;
            max-width: 600px;
            padding: 30px;
            text-align: center;
        }

        h1 {
            color: #333;
            margin-bottom: 10px;
            font-size: 28px;
        }

        .description {
            color: #666;
            margin-bottom: 30px;
            font-size: 16px;
            line-height: 1.5;
        }

        .status {
            background-color: #f0f0f0;
            border-radius: 10px;
            padding: 15px;
            margin-bottom: 25px;
            min-height: 60px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }

        .status-text {
            font-size: 18px;
            font-weight: 600;
            margin-bottom: 10px;
        }

        .recording-indicator {
            display: inline-block;
            width: 12px;
            height: 12px;
            background-color: #ff3b30;
            border-radius: 50%;
            margin-right: 8px;
            animation: pulse 1.5s infinite;
        }

        @keyframes pulse {
            0% { opacity: 1; }
            50% { opacity: 0.5; }
            100% { opacity: 1; }
        }

        .timer {
            font-size: 24px;
            font-weight: bold;
            color: #333;
            font-family: monospace;
        }

        .controls {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-bottom: 25px;
            flex-wrap: wrap;
        }

        button {
            padding: 12px 25px;
            border: none;
            border-radius: 50px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
            min-width: 140px;
        }

        .record-btn {
            background-color: #ff3b30;
            color: white;
        }

        .record-btn:hover {
            background-color: #ff6961;
            transform: translateY(-2px);
        }

        .pause-btn {
            background-color: #ff9500;
            color: white;
        }

        .pause-btn:hover {
            background-color: #ffb143;
            transform: translateY(-2px);
        }

        .stop-btn {
            background-color: #4cd964;
            color: white;
        }

        .stop-btn:hover {
            background-color: #5fe081;
            transform: translateY(-2px);
        }

        .play-btn {
            background-color: #007aff;
            color: white;
        }

        .play-btn:hover {
            background-color: #5ac8fa;
            transform: translateY(-2px);
        }

        .download-btn {
            background-color: #5856d6;
            color: white;
        }

        .download-btn:hover {
            background-color: #7d7cdf;
            transform: translateY(-2px);
        }

        button:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
            transform: none;
        }

        .audio-container {
            margin-top: 20px;
            display: none;
        }

        audio {
            width: 100%;
            margin-top: 10px;
        }

        .visualizer {
            width: 100%;
            height: 100px;
            background-color: #f0f0f0;
            border-radius: 10px;
            margin-top: 20px;
            overflow: hidden;
            display: none;
        }

        .visualizer-bar {
            display: inline-block;
            width: 4px;
            margin: 0 1px;
            background-color: #6a11cb;
            border-radius: 2px;
        }

        .footer {
            margin-top: 30px;
            color: #666;
            font-size: 14px;
        }

        @media (max-width: 600px) {
            .container {
                padding: 20px;
            }

            button {
                min-width: 120px;
                padding: 10px 20px;
            }

            .controls {
                gap: 10px;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <h1>录音应用</h1>
    <p class="description">使用此应用录制音频并保存为WebM格式。点击"开始录音"按钮开始录制。</p>

    <div class="status">
        <div class="status-text">准备录音</div>
        <div class="timer">00:00</div>
    </div>

    <div class="visualizer" id="visualizer"></div>

    <div class="controls">
        <button id="recordBtn" class="record-btn">
            <span>●</span> 开始录音
        </button>
        <button id="pauseBtn" class="pause-btn" disabled>
            <span>❚❚</span> 暂停
        </button>
        <button id="stopBtn" class="stop-btn" disabled>
            <span>■</span> 停止
        </button>
        <button id="playBtn" class="play-btn" disabled>
            <span>▶</span> 播放
        </button>
        <button id="downloadBtn" class="download-btn" disabled>
            <span>↓</span> 下载
        </button>
    </div>

    <div class="audio-container" id="audioContainer">
        <p>录制完成！您可以播放或下载录音：</p>
        <audio id="audioPlayback" controls></audio>
    </div>

    <div class="footer">
        <p>录音将保存为WebM格式，支持大多数现代浏览器</p>
    </div>
</div>

<script>
    // 获取DOM元素
    const recordBtn = document.getElementById('recordBtn');
    const pauseBtn = document.getElementById('pauseBtn');
    const stopBtn = document.getElementById('stopBtn');
    const playBtn = document.getElementById('playBtn');
    const downloadBtn = document.getElementById('downloadBtn');
    const audioPlayback = document.getElementById('audioPlayback');
    const audioContainer = document.getElementById('audioContainer');
    const statusText = document.querySelector('.status-text');
    const timer = document.querySelector('.timer');
    const visualizer = document.getElementById('visualizer');

    // 录音相关变量
    let mediaRecorder;
    let audioChunks = [];
    let audioBlob;
    let audioUrl;
    let startTime;
    let timerInterval;
    let isRecording = false;
    let isPaused = false;
    let audioContext;
    let analyser;
    let dataArray;
    let bufferLength;
    let animationId;

    // 检查浏览器支持
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
        statusText.innerHTML = "您的浏览器不支持录音功能，请使用Chrome、Firefox或Edge等现代浏览器。";
        recordBtn.disabled = true;
    }

    // 开始录音
    recordBtn.addEventListener('click', async () => {
        try {
            // 请求麦克风权限
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });

            // 设置音频分析器用于可视化
            setupAudioAnalyser(stream);

            // 创建MediaRecorder实例
            mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' });

            // 录音数据可用时的处理
            mediaRecorder.ondataavailable = (event) => {
                if (event.data.size > 0) {
                    audioChunks.push(event.data);
                }
            };

            // 录音停止时的处理
            mediaRecorder.onstop = () => {
                // 创建Blob对象
                audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
                audioUrl = URL.createObjectURL(audioBlob);

                // 设置音频播放源
                audioPlayback.src = audioUrl;

                // 显示音频播放器
                audioContainer.style.display = 'block';

                // 停止可视化
                cancelAnimationFrame(animationId);
                visualizer.style.display = 'none';

                // 更新状态
                statusText.innerHTML = "录音完成";

                // 启用播放和下载按钮
                playBtn.disabled = false;
                downloadBtn.disabled = false;

                // 释放麦克风资源
                stream.getTracks().forEach(track => track.stop());
            };

            // 开始录音
            mediaRecorder.start();
            isRecording = true;

            // 更新按钮状态
            recordBtn.disabled = true;
            pauseBtn.disabled = false;
            stopBtn.disabled = false;
            playBtn.disabled = true;
            downloadBtn.disabled = true;

            // 更新状态
            statusText.innerHTML = '<span class="recording-indicator"></span>正在录音...';

            // 显示可视化
            visualizer.style.display = 'block';

            // 开始计时
            startTimer();

        } catch (error) {
            console.error("录音错误:", error);
            statusText.innerHTML = "录音失败: " + error.message;
        }
    });

    // 暂停/继续录音
    pauseBtn.addEventListener('click', () => {
        if (isRecording) {
            if (!isPaused) {
                mediaRecorder.pause();
                pauseBtn.innerHTML = '<span>▶</span> 继续';
                statusText.innerHTML = "录音已暂停";
                isPaused = true;
                clearInterval(timerInterval);
            } else {
                mediaRecorder.resume();
                pauseBtn.innerHTML = '<span>❚❚</span> 暂停';
                statusText.innerHTML = '<span class="recording-indicator"></span>正在录音...';
                isPaused = false;
                startTimer();
            }
        }
    });

    // 停止录音
    stopBtn.addEventListener('click', () => {
        if (isRecording) {
            mediaRecorder.stop();
            isRecording = false;

            // 更新按钮状态
            recordBtn.disabled = false;
            pauseBtn.disabled = true;
            stopBtn.disabled = true;

            // 停止计时
            clearInterval(timerInterval);
        }
    });

    // 播放录音
    playBtn.addEventListener('click', () => {
        audioPlayback.play();
    });

    // 下载录音
    downloadBtn.addEventListener('click', () => {
        const a = document.createElement('a');
        a.href = audioUrl;
        a.download = `recording-${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.webm`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    });

    // 计时器函数
    function startTimer() {
        startTime = Date.now();
        clearInterval(timerInterval);

        timerInterval = setInterval(() => {
            const elapsedTime = Date.now() - startTime;
            const seconds = Math.floor(elapsedTime / 1000) % 60;
            const minutes = Math.floor(elapsedTime / (1000 * 60));

            timer.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
        }, 1000);
    }

    // 设置音频分析器用于可视化
    function setupAudioAnalyser(stream) {
        audioContext = new (window.AudioContext || window.webkitAudioContext)();
        analyser = audioContext.createAnalyser();
        const source = audioContext.createMediaStreamSource(stream);
        source.connect(analyser);

        analyser.fftSize = 256;
        bufferLength = analyser.frequencyBinCount;
        dataArray = new Uint8Array(bufferLength);

        // 开始可视化
        drawVisualizer();
    }

    // 绘制音频可视化
    function drawVisualizer() {
        animationId = requestAnimationFrame(drawVisualizer);

        analyser.getByteFrequencyData(dataArray);

        // 清空可视化区域
        visualizer.innerHTML = '';

        // 创建可视化条
        for (let i = 0; i < bufferLength; i++) {
            const barHeight = dataArray[i] / 2;
            const bar = document.createElement('div');
            bar.className = 'visualizer-bar';
            bar.style.height = `${barHeight}px`;
            visualizer.appendChild(bar);
        }
    }
</script>
</body>
</html>